"""Compiled version of a DataWarehouse IssueRegex."""
import dataclasses
import functools
import re
import typing

from cki_lib.logger import get_logger
from datawarehouse import objects

from . import cache

LOGGER = get_logger(__name__)


@dataclasses.dataclass
class CompiledIssueRegex:
    # pylint: disable=too-many-instance-attributes
    """Compiled version of a DataWarehouse IssueRegex."""

    id: int
    issue: dict
    issue_id: int
    issue_description: str
    valid: bool

    text_match: typing.Optional[re.Pattern[str]]
    test_name_match: typing.Optional[re.Pattern[str]]
    testresult_name_match: typing.Optional[re.Pattern[str]]
    file_name_match: typing.Optional[re.Pattern[str]]
    tree_match: typing.Optional[re.Pattern[str]]
    kpet_tree_name_match: typing.Optional[re.Pattern[str]]
    architecture_match: typing.Optional[re.Pattern[str]]
    package_name_match: typing.Optional[re.Pattern[str]]


def get_compiled_issueregexes(issueregex_ids: list[int]) -> list[CompiledIssueRegex]:
    """Call _get_compiled_issueregexes with cache hash."""
    return _get_compiled_issueregexes(
        cache.get_cache_ttl(),
        # list is not hashable, tuple is necessary for lru_cache
        tuple(issueregex_ids),
    )


@functools.lru_cache(maxsize=1)
def _get_compiled_issueregexes(
    ttl_hash: int,
    issueregex_ids: tuple[int],
) -> list[CompiledIssueRegex]:
    """Download and compile regexes from Datawarehouse."""
    return [c for r in cache.get_issueregexes(ttl_hash, issueregex_ids)
            if (c := compile_issueregex(r)).valid]


def compile_issueregex(dw_issueregex: objects.IssueRegex) -> CompiledIssueRegex:
    """Compile an IssueRegex into a CompiledIssueRegex."""
    init_args = {
        'id': dw_issueregex.id,
        'issue_id': dw_issueregex.issue['id'],
        'issue': dw_issueregex.issue,
        'issue_description': dw_issueregex.issue['description'],
        'valid': True,
    }
    for field in dataclasses.fields(CompiledIssueRegex):
        if field.name.endswith('_match'):
            regex = getattr(dw_issueregex, field.name)
            try:
                init_args[field.name] = re.compile(regex) if regex else None
            except re.error as error:
                LOGGER.error("Bad regex pattern %r for %r in issueregex %s: %s",
                             regex, field.name, dw_issueregex.id, str(error))
                init_args['valid'] = False
                init_args[field.name] = None
    return CompiledIssueRegex(**init_args)
